Amazon MSK Serverlessにパブリックアクセスしてみた #reinvent
いわさです。
re:Invent 2021にてAmazon MSK Serverlessがパブリックプレビューで登場しました。
MSKサーバーレスはクラスター構築時にVPCを関連付けする必要があり、VPC内からのみのアクセスが可能です。
そして、現時点でサーバーレスクラスターにはパブリックアクセス機能は提供されておりません。
Amazon MSKでブローカーノードへの接続時にパブリックアクセスを構成出来るようになりました | DevelopersIO
MSKサーバーレスの紹介記事の中で以下のように少しパブリックアクセスの可能性について言及させてもらっていました。
もしかしたらNLBだと出来るかもしれない。今度試してみます。
気になってたので、本日はこちらを試してみました。
MSK Serverlessは本日時点でパブリックプレビューです。今後のアップデートで本検証と異なる結果になる可能性があります。
MSKサーバーレスクラスターとNetwork Load Balancerを作成
まずはMSKサーバーレスクラスターを作成します。
VPC内のインスタンスから名前解決してみると、VPCエンドポイントへのCNAMEが使われていました。
sh-4.2$ nslookup boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com Server: 172.31.0.2 Address: 172.31.0.2#53 Non-authoritative answer: boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com canonical name = vpce-02e94f6fa85a517a4-g6c6fs45.vpce-svc-05e4c72627dde0f5b.us-east-2.vpce.amazonaws.com. Name: vpce-02e94f6fa85a517a4-g6c6fs45.vpce-svc-05e4c72627dde0f5b.us-east-2.vpce.amazonaws.com Address: 172.31.18.113 Name: vpce-02e94f6fa85a517a4-g6c6fs45.vpce-svc-05e4c72627dde0f5b.us-east-2.vpce.amazonaws.com Address: 172.31.8.19 Name: vpce-02e94f6fa85a517a4-g6c6fs45.vpce-svc-05e4c72627dde0f5b.us-east-2.vpce.amazonaws.com Address: 172.31.46.215
ネットワークインターフェイス(ENI)を見てみましょう。
NLBでTCP9098をルーティングしてやると動きそうな気もしますね。
では、作成されたENIに向けてパブリックアクセス出来るネットワークロードバランサーを作成します。
接続元(MSKクライアント)からアクセス出来るようにセキュリティグループ許可を設定しておきます。
接続してみる
MSKサーバーレスクラスターはIAM認証のみ許可されています。
クライアント環境は前回macOS上でHomebrewを使ってセットアップした環境がIAM認証でパブリックアクセスする設定になっているのでこれをそのまま使ってみます。
マネジメントコンソール上のブートストラップサーバーはboot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098
となっていましたが、これをこのまま使うと名前解決が出来ません。
なので、ホスト部分をネットワークロードバランサーに変更(nlb-external-d45dfa4f0ff6ee7f.elb.us-east-2.amazonaws.com:9098
)して、これをブートストラップサーバーとして指定して接続してみましょう。
[2021-12-06 07:25:19,660] WARN [AdminClient clientId=adminclient-1] Metadata update failed due to authentication error (org.apache.kafka.clients.admin.internals.AdminMetadataManager) org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching nlb-external-d45dfa4f0ff6ee7f.elb.us-east-2.amazonaws.com found.
SSLでの通信に失敗しました。
ドメイン名をどうにかすればいける可能性がありますが、一旦SSLを無効化して試してみましょう。
クライアント構成ファイルでSASL_SSL
を指定しています。
IAM認証は回避できない気がするのでSASLのみを設定(SASL_PLAINTEXT
)してみましょう。
# security.protocol = SASL_SSL security.protocol = SASL_PLAINTEXT sasl.mechanism = AWS_MSK_IAM sasl.jaas.config = software.amazon.msk.auth.iam.IAMLoginModule required awsProfileName="hoge"; sasl.client.callback.handler.class = software.amazon.msk.auth.iam.IAMClientCallbackHandler
iwasa.takahito@hoge ~ % export BS=nlb-external-d45dfa4f0ff6ee7f.elb.us-east-2.amazonaws.com:9098 iwasa.takahito@hoge ~ % kafka-topics --bootstrap-server $BS --command-config client.properties --create --topic hoge-msk-serverless --partitions 6 --replication-factor 1 Error while executing topic command : The AdminClient thread has exited. Call: createTopics [2021-12-06 09:13:09,128] ERROR org.apache.kafka.common.errors.TimeoutException: The AdminClient thread has exited. Call: createTopics (kafka.admin.TopicCommand$) [2021-12-06 09:13:09,130] ERROR Uncaught exception in thread 'kafka-admin-client-thread | adminclient-1': (org.apache.kafka.common.utils.KafkaThread)
やはり接続できないですね。
今回はSSL接続を行うために、hostsファイルを使ってローカルで名前解決してMSKクライアントを使ってみたいと思います。
NLBのパブリックIPアドレスをhostsファイルに設定します。
iwasa.takahito@hoge ~ % cat /etc/hosts 127.0.0.1 localhost 255.255.255.255 broadcasthost ... 3.22.72.13 boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com
iwasa.takahito@hoge ~ % export BS=boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098 iwasa.takahito@hoge ~ % kafka-topics --bootstrap-server $BS --command-config client.properties --create --topic hoge-msk-serverless --partitions 6 --replication-factor 1 [2021-12-06 09:22:55,669] WARN [AdminClient clientId=adminclient-1] Error connecting to node b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098 (id: 97 rack: null) (org.apache.kafka.clients.NetworkClient) java.net.UnknownHostException: b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com: nodename nor servname provided, or not known ... [2021-12-06 09:22:55,753] WARN [AdminClient clientId=adminclient-1] Error connecting to node b481-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098 (id: 481 rack: null) (org.apache.kafka.clients.NetworkClient) java.net.UnknownHostException: b481-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com: nodename nor servname provided, or not known ... [2021-12-06 09:22:55,754] WARN [AdminClient clientId=adminclient-1] Error connecting to node b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098 (id: 97 rack: null) (org.apache.kafka.clients.NetworkClient) java.net.UnknownHostException: b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com ... [2021-12-06 09:22:55,835] WARN [AdminClient clientId=adminclient-1] Error connecting to node b465-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com:9098 (id: 465 rack: null) (org.apache.kafka.clients.NetworkClient) java.net.UnknownHostException: b465-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com: nodename nor servname provided, or not known ...
先程とまた違うエラーメッセージが大量に表示されましたね。
ブートストラップサーバーからブローカーノードの一覧を受け取って、各ノードへアクセスするのですが、各ブローカーサーバーの名前解決が出来ていません。
わかる範囲でhostsへ追加してみます。
3.22.72.13 boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b265-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b481-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b225-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com
iwasa.takahito@hoge ~ % kafka-topics --bootstrap-server $BS --command-config client.properties --create --topic hoge-msk-serverless --partitions 6 --replication-factor 1 Created topic hoge-msk-serverless.
おぉ、VPC外からトピックの作成に成功しました!!
その後、プロデューサー、コンシューマーそれぞれから接続する際も同様にブローカーノードへ接続できない旨が大量に表示されるので、同じようにhostsに追加していきました。
大量に出るエラーメッセージのうち数件分だけ...
3.22.72.13 boot-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b97-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b265-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b481-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b225-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b65-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b81-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b465-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b73-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b377-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com 3.22.72.13 b337-otr5ye0h.c1.kafka-serverless.us-east-2.amazonaws.com
その結果、プロデューサーとコンシューマーもパブリックアクセスが出来ました。
iwasa.takahito@hoge ~ % kafka-console-producer --bootstrap-server $BS --producer.config client.properties --topic hoge-msk-serverless >111 >222 >333 ... iwasa.takahito@hoge ~ % kafka-console-consumer --bootstrap-server $BS --consumer.config client.properties --topic hoge-msk-serverless --from-beginning 111 222 333
まとめ
VPC外からパブリックアクセス自体は出来ました。
しかし全く実用的じゃないですね。
名前解決の問題もありますし、ブローカーノード情報や各IPアドレスも固定とみなして設定して終わりにはならない気がします。
どうにか接続は出来なくもないですが、おとなしくVPC内で利用するのが良さそう。というところでしょうか。